"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

from msnp.service.network.model.CustodyModel import CustodyQueueType, \
    GroupsReicevedMessage, GroupDetailsReceivedMessage, \
    MemberStatusChangedMessage, ResponsibleIdentityFoundMessage, \
    MediaContentMessage, PersonalMessage, PersonalMessageCallback
from msnp.logger import Logger
from msnp.service.network.model.CustodyModel import AuthMessage, HelloMessage, \
     ShiftedPeerMessage
from msnp.service.network.model import CustodyModel


#####################
## BUNDLE_MESSAGES ##
#####################
    
# a list of CustodyMessage-objects
__preservedMessages = []


#################
## ADD_MESSAGE ##
#################
    
def addCustodyMessages(messages):
    """This function adds new messages to the queue.
    
    Args:
        messages: a list of CustodyMessage instances
    """
    
    global __preservedMessages
    if messages != None and len(messages) > 0:
        for msg in messages:
            if msg != None:
                Logger.info("got msg for peer " + msg.getName() + " of type " + msg.getQueueType())
                __preservedMessages.append(msg)
        
        
def addAuthMessage(name, authValidationType):
    """This function adds a new AuthMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        authValidationType: the result of the authentication validation (defined by ReturnType)
    """
    
    global __preservedMessages
    authMsg = AuthMessage(name, authValidationType)
    __preservedMessages.append(authMsg)


def addHelloMessage(name, responsibleIdentity, isLogin):
    """This function adds a new HelloMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        responsibleIdentity: the responsible identity (PeerInfo instance)
        isLogin: a boolean determining whether the underlying authentication process is a login or a registration
    """
    
    global __preservedMessages
    helloMsg = HelloMessage(name, responsibleIdentity, isLogin)
    __preservedMessages.append(helloMsg)


def addResponsibleIdentityFoundMessage(name, respIdentity, searchedName, result, reactType):
    """This function adds a new ResponsibleIdentityFoundMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        respIdentity: the responsible identity (PeerInfo instance)
        searchedName: the name of the searched identity (string)
        result: the result, defined by PTPModel.ReturnType
        reactType: defined by Model.CallbackReactType
    """
    
    global __preservedMessages
    respMsg = ResponsibleIdentityFoundMessage(name, respIdentity, searchedName, result, reactType)
    __preservedMessages.append(respMsg)
    
    
def addShiftedPeerMessage(name, newSuperPeer):
    """This function adds a new ShiftedPeerMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        newSuperPeer: the new responsible identity (PeerInfo instance)
    """
    
    global __preservedMessages
    shiftMsg = ShiftedPeerMessage(name, newSuperPeer)
    __preservedMessages.append(shiftMsg)
    
    
def addGroupsReceivedMessage(name, groups, reactType, searchFinished):
    """This function adds a new GroupsReicevedMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        groups: a list of groups that correspond to the search criteria
        reactType: defined by Model.CallbackReactType
        searchFinished: a boolean which determines whether the search is finished or not.
    """
    
    global __preservedMessages
    groupMsg = GroupsReicevedMessage(name, groups, reactType, searchFinished)
    __preservedMessages.append(groupMsg)


def addGroupDetailsReceivedMessage(name, group, reactType):
    """This function adds a new GroupDetailsReceivedMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        group: a group (PTPModel.Group instance), containing all details.
        reactType: defined by Model.CallbackReactType
    """
    
    global __preservedMessages
    groupDetMsg = GroupDetailsReceivedMessage(name, group, reactType)
    __preservedMessages.append(groupDetMsg)
    
    
def addMemberStatusChangedMessage(name, membername, groupname, ownername, result, status):
    """This function adds a new MemberStatusChangedMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        membername: the name of the member (string)
        groupanme: the name of the group (string)
        ownername: the name of the owner (string)
        result: the result, defined by PTPModel.ReturnType
        status: the status
    """
    
    global __preservedMessages
    statusMsg = MemberStatusChangedMessage(name, membername, groupname, ownername, result, status, False)
    __preservedMessages.append(statusMsg)
    
    
def addMediaContentMessage(name, content, timestamp):
    """This function adds a new MediaContentMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        content: the transmitted media content.
        timestamp: the time stamp
    """
    
    global __preservedMessages
    contentMsg = MediaContentMessage(name, content, timestamp)
    __preservedMessages.append(contentMsg)


def addGetMediaContentSinceLastSynchMessage(name, senderIdentity, senderName, group, timestamp):
    """This function adds a new GetMediaContentSinceLastSynchMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        senderIdentity: the sender (PeerInfo instance)
        genres: a list of genres
        senderName: the name of the sender
        timestamp: the time stamp
    """
    
    global __preservedMessages
    contentMsg = CustodyModel.GetMediaContentSinceLastSynchMessage(name, senderIdentity, senderName, group, timestamp)
    __preservedMessages.append(contentMsg)
    
    
def addPersonalMessage(receiverName, senderName, message, timestamp):
    """This function adds a new PersonalMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        senderName: the name of the sender
        message: the message (string)
        timestamp: the time stamp
    """
    
    global __preservedMessages
    pMsg = PersonalMessage(receiverName, senderName, message, timestamp)
    __preservedMessages.append(pMsg)
    
    
def addPersonalMessageCallback(receiverName, senderName, timestamp, status):
    """This function adds a new PersonalMessage instance to the queue.
    
    Args:
        name: the name of the low level peer (string)
        senderName: the name of the sender
        status: the status of the personal message request
        timestamp: the time stamp
    """
    
    global __preservedMessages
    pMsg = PersonalMessageCallback(receiverName, senderName, timestamp, status)
    __preservedMessages.append(pMsg)
        
        
######################
## RETRIEVE_MESSAGE ##
######################
        
def retrieveAndDelete(name, queueType, delete=True):
    """This function retrieves all messages for the peer with the given name that are of type 'queueType'.
    
    If 'queueType' is ALL_TYPES it retrieves all kept messages, otherwise only the messages of type 'queueType'.
    If 'delete' is True the retrieved messages are also deleted from the queue.
    
    Args:
        name: the name of the low level peer (string)
        queueType: the type of the messages that have to be retrieved (defined by CustodyQueueType)
        delete: true if the retrieved messages have to be deleted afterwards
        
    Returns:
        A list of CustodyMessage instances
    """
    
    if queueType == CustodyQueueType.ALL_TYPES:
        return __retrieveAndDeleteAllKeptMessagesForNameAndQueueType(name, None, delete)
    else:
        return __retrieveAndDeleteAllKeptMessagesForNameAndQueueType(name, queueType, delete);
    
    
def retrieveAndDeleteList(name, queueTypeList, delete=True):
    """This function retrieves all messages for the peer with the given name that are of one of the types in 'queueTypeList'.
    
    If 'delete' is True the retrieved messages are also deleted from the queue.
    
    Args:
        name: the name of the low level peer (string)
        queueTypeList: a list of message types that have to be retrieved (defined by CustodyQueueType)
        delete: true if the retrieved messages have to be deleted afterwards
        
    Returns:
        A list of CustodyMessage instances
    """
    
    messageList = []
    for queueType in queueTypeList:
        temp = retrieveAndDelete(name, queueType, delete)
        for message in temp:
            messageList.append(message)
    return messageList


def __retrieveAndDeleteAllKeptMessagesForNameAndQueueType(name, queueType=None, delete=True):
    """This function retrieves all messages for the peer with the given name that are of type 'queueType'.
    
    If 'delete' is True the retrieved messages are also deleted from the queue.
    
    Args:
        name: the name of the low level peer (string)
        queueType: the type of the messages that have to be retrieved (defined by CustodyQueueType)
        delete: true if the retrieved messages have to be deleted afterwards
        
    Returns:
        A list of CustodyMessage instances
    """
    
    global __preservedMessages
    allMessages = []
    for msg in __preservedMessages:
        if msg.getName() == name and (queueType == None or msg.getQueueType() == queueType):
            allMessages.append(msg)
    if delete:
        for msg in allMessages:
            __preservedMessages.remove(msg)
    return allMessages


####################
## DELETE_MESSAGE ##
####################

def deleteAllMessages():
    """This function deletes all kept messages.
    """
    
    global __preservedMessages
    for msg in __preservedMessages:
        __preservedMessages.remove(msg)


def deleteAllMessagesForName(name):
    """This method deletes all messages for the given user name.
    
    Args:
        name: the user name (string)
    """
    
    global __preservedMessages
    for msg in __preservedMessages:
        if msg.getName() == name:
            __preservedMessages.remove(msg)
    

##############
## CONTAINS ##
##############

def containsShiftMessageFor(name):
    """This method determines whether there are messages with type SHIFT_PEER_MESSAGE stored for the given user name.
    
    Args:
        name: the user name (string)
        
    Returns:
        True if there are messages with type SHIFT_PEER_MESSAGE stored for the given user name, False otherwise
    """
    
    global __preservedMessages
    for msg in __preservedMessages:
        if msg.getQueueType == CustodyQueueType.SHIFT_PEER_MESSAGE:
            if msg.getName() == name:
                return True
    return False
    
